Ошибка TS2353: Object literal may only specify known на базе prisma nodejs

Ошибка TS2353: Object literal may only specify known properties возникает, потому что Prisma не поддерживает свойство mode в фильтрах строк (StringFilter) для метода findMany. Это свойство используется для указания нечувствительности к регистру, но оно доступно только в некоторых контекстах, например, при использовании полнотекстового поиска или в определенных базах данных.


Решение проблемы

Чтобы реализовать поиск по LIKE с учетом нечувствительности к регистру, можно использовать встроенные возможности Prisma и базы данных. Вот несколько подходов:


1. Использование contains без mode

Если ваша база данных по умолчанию поддерживает нечувствительность к регистру (например, MySQL с utf8_general_ci), вы можете просто убрать mode:

typescript

async getAllDocumentsByNameTypeId(name: string, typeId: number) {
  return this.prisma.documents.findMany({
    where: {
      name: {
        contains: name, // Поиск по частичному совпадению
      },
      ...(typeId !== 0 && { typeId: Number(typeId) }), // Условие для typeId
    },
  });
}

  • Плюсы: Простое решение, работает, если база данных уже настроена на нечувствительность к регистру.
  • Минусы: Если база данных чувствительна к регистру, поиск будет учитывать регистр.

2. Преобразование строки в нижний регистр

Если база данных чувствительна к регистру, можно преобразовать строки в нижний регистр как в запросе, так и в базе данных. Это можно сделать с помощью Prisma raw запросов или функций базы данных.Пример с использованием Prisma и PostgreSQL:

typescript

async getAllDocumentsByNameTypeId(name: string, typeId: number) {
  return this.prisma.documents.findMany({
    where: {
      name: {
        contains: name.toLowerCase(), // Преобразуем строку в нижний регистр
      },
      ...(typeId !== 0 && { typeId: Number(typeId) }),
    },
  });
}

  • Плюсы: Работает с базами данных, чувствительными к регистру.
  • Минусы: Может быть менее производительным, если база данных не оптимизирована для таких запросов.

3. Использование Prisma.raw для кастомных SQL-запросов

Если вам нужно явно указать нечувствительность к регистру, можно использовать Prisma.raw для выполнения SQL-запросов напрямую:

typescript

import { Prisma } from '@prisma/client';

async getAllDocumentsByNameTypeId(name: string, typeId: number) {
  const query = `
    SELECT * FROM "Documents"
    WHERE LOWER("name") LIKE LOWER($1)
    ${typeId !== 0 ? 'AND "typeId" = $2' : ''}
  `;

  const params = typeId !== 0 ? [`%${name}%`, typeId] : [`%${name}%`];

  return this.prisma.$queryRaw(Prisma.sql([query, ...params]));
}

  • Плюсы: Полный контроль над SQL-запросом.
  • Минусы: Потеря типизации Prisma и сложность поддержки.

4. Настройка базы данных

Если вы используете MySQL, вы можете настроить нечувствительность к регистру на уровне базы данных, например, с помощью COLLATE:

sql

ALTER TABLE Documents MODIFY name VARCHAR(255) COLLATE utf8_general_ci;

  • Плюсы: Решение на уровне базы данных, не требует изменений в коде.
  • Минусы: Требует доступа к настройкам базы данных.

Рекомендация

Если ваша база данных поддерживает нечувствительность к регистру по умолчанию, используйте вариант 1. Если нет, и вы хотите минимизировать изменения в коде, используйте вариант 2 с преобразованием строки в нижний регистр.


Обновленный метод

Вот финальная версия метода с учетом всех условий:

typescript

async getAllDocumentsByNameTypeId(name: string, typeId: number) {
  return this.prisma.documents.findMany({
    where: {
      name: {
        contains: name, // Поиск по частичному совпадению
      },
      ...(typeId !== 0 && { typeId: Number(typeId) }), // Условие для typeId
    },
  });
}

Если база данных чувствительна к регистру, используйте преобразование строки в нижний регистр:

typescript

async getAllDocumentsByNameTypeId(name: string, typeId: number) {
  return this.prisma.documents.findMany({
    where: {
      name: {
        contains: name.toLowerCase(), // Преобразуем строку в нижний регистр
      },
      ...(typeId !== 0 && { typeId: Number(typeId) }),
    },
  });
}